using System;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Globalization;
using System.ComponentModel;
using System.Collections;

namespace GoodStuff.Web.Controls
{
	/// <summary>
	/// This CheckBoxList list fixes the line wrapping problem with long option texts. It
	/// also provides a way to databind the initial selection.
	/// </summary>
	/// <remarks>
	/// For information about how to bind the initial values, see the <see cref="SelectedValues"/> property.
	/// </remarks>
	public class WrappingCheckBoxList : System.Web.UI.WebControls.CheckBoxList, IRepeatInfoUser
	{
		private object _selectedValues = null;
		private string _selectedValuesDataMember = String.Empty;

		public WrappingCheckBoxList()
		{
			base.RepeatLayout = System.Web.UI.WebControls.RepeatLayout.Table;

			this.controlToRepeat = new CheckBox();
			this.controlToRepeat.ID = "0";
			this.controlToRepeat.EnableViewState = false;
			this.Controls.Add(this.controlToRepeat);
		}

		/// <summary>
		/// Contains the datasource for the selected values 
		/// </summary>
		/// <remarks>
		/// The list of selected values should be a subset of the datasource, but the container type
		/// may vary. To define which property of the argument defines the selection value, specify the
		/// <see cref="SelectedValuesDataMember"/>.
		/// </remarks>
		[Bindable(true),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
		Category("Data"), 
		DefaultValue((string) null)
		]
		public object SelectedValues
		{
			get { return _selectedValues; }
			set 
			{ 
				if (((value != null) && !(value is IListSource)) && !(value is IEnumerable))
				{
					throw new ArgumentException(this.ID + " must be IListSource or IEnumerable");
				}

				_selectedValues = value; 
			}
		}

		/// <summary>
		/// In case the SelectedValues property is a collection of objects,
		/// this member indicate the value of the item, the same way that the
		/// DataValueField works.
		/// </summary>
		[DefaultValue(""), Category("Data")]
		public string SelectedValuesDataMember
		{
			get { return _selectedValuesDataMember; }
			set { _selectedValuesDataMember = value; }
		}

		protected override void OnDataBinding(EventArgs e)
		{
			base.OnDataBinding (e);
			if(SelectedValues != null)
			{
				this.ClearSelection();
				IEnumerable selectionList = (IEnumerable)SelectedValues;
				foreach(object obj in selectionList)
				{
					string val;
					if(SelectedValuesDataMember.Length != 0)
					{
						val = DataBinder.GetPropertyValue(obj, SelectedValuesDataMember, null);
					}
					else
					{
						val = obj.ToString();
					}

					ListItem foundItem = this.Items.FindByValue(val);
					if(foundItem != null)
					{
						foundItem.Selected = true;
					}
				}
			}
		}

		protected override void Render(HtmlTextWriter writer)
		{
			RepeatInfo info1 = new RepeatInfo();
			Style style1 = base.ControlStyleCreated ? base.ControlStyle : null;
			short num1 = this.TabIndex;
			bool flag1 = false;
			this.controlToRepeat.TabIndex = num1;
			if (num1 != 0)
			{
				if (!this.ViewState.IsItemDirty("TabIndex"))
				{
					flag1 = true;
				}
				this.TabIndex = 0;
			}
			info1.RepeatColumns = this.RepeatColumns;
			info1.RepeatDirection = this.RepeatDirection;
			info1.RepeatLayout = this.RepeatLayout;
			info1.RenderRepeater(writer, this, style1, this);
			if (num1 != 0)
			{
				this.TabIndex = num1;
			}
			if (flag1)
			{
				this.ViewState.SetItemDirty("TabIndex", false);
			}
		}

 		protected override void OnPreRender(EventArgs e)
		{
			this.controlToRepeat.AutoPostBack = this.AutoPostBack;
			if (this.Page != null)
			{
				for (int num1 = 0; num1 < this.Items.Count; num1++)
				{
					this.controlToRepeat.ID = num1.ToString(NumberFormatInfo.InvariantInfo);
					this.Page.RegisterRequiresPostBack(this.controlToRepeat);
				}
			}
		}

		public override RepeatLayout RepeatLayout
		{
			get
			{
				return base.RepeatLayout;
			}
			set
			{
				if(value != System.Web.UI.WebControls.RepeatLayout.Table)
				{
					throw new NotSupportedException("The WrappingRadioButtonList only works with RepeatLayout.Table");
				}
				base.RepeatLayout = value;
			}
		}

		void IRepeatInfoUser.RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
		{
			this.controlToRepeat.ID = repeatIndex.ToString(NumberFormatInfo.InvariantInfo);
			this.controlToRepeat.Text = null; //this.Items[repeatIndex].Text;
			this.controlToRepeat.TextAlign = this.TextAlign;
			this.controlToRepeat.Checked = this.Items[repeatIndex].Selected;
			this.controlToRepeat.Enabled = this.Enabled;
			this.controlToRepeat.RenderControl(writer);

			writer.Write("</td><td>");

			writer.Write("<label for=\"" + this.controlToRepeat.ClientID + "\">");
			writer.Write(this.Items[repeatIndex].Text);
			writer.Write("</label>");
		}

		private CheckBox controlToRepeat;
	}
}
